package com.cskaoyan.javase.recursion._0introduction;

/**
 * 递归的引入,递归的简单实用
 * 我们已经学习过方法，使用过方法了。方法体中是可以调用方法的，那么如果在方法体中调用方法自身呢？
 * 特别的，在一个方法当中再次调用这个方法，就像故事里提到同样的故事一样，我们把方法在运行时调用自身的情况，称之为递归，又叫做递归调用。
 *
 * 递归的使用:
 *      1.要想使用递归,方法必须在方法体中调用自身,在java中把方法中调用自身的语句,称之为"递归体".
 *      2.只有递归体的递归显然是不合格的,会无限递归导致栈溢出.递归需要出口
 *      3.思考:
 *          递归有递归体,也有递归的出口,那么就是安全的吗?
 *          不是,即便有了递归的出口,但如果出口过于遥远,在递归过程中仍然可能栈溢出
 *     所以递归还需要考虑递归的次数(递归的深度)
 *     递归的深度如果超出了栈内存空间,仍然会栈溢出.
 *
 * 总结一下:
 * 递归的三要素:
 *      1.递归体
 *      2.递归的出口
 *      3.递归的深度
 * 以上递归的使用实际上是比较危险的,稍有不慎就会引发栈溢出错误.
 *
 * @since 16:30
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        System.out.println(sum(16000));
        /*
            分析一下这个程序:
            sum(10) = 10 + sum(9);
            sum(9) = 9 + sum(8);
            sum(8) = 8 + sum(7);
            sum(7) = 7 + sum(6);
            .....
            这个过程显然是停不下来的
            那么有可能有以下结果:
            1.死循环
            2.电脑直接炸了
            3.报错

            实际上,程序会抛出异常,报错终止
            抛出的异常是: StackOverflowError
            栈溢出错误,首先Error是比Exception更为严重的错误,一般情况下,程序出现错误都是非常严重的问题.
            这个栈是什么栈? 是JVM栈
            为什么JVM栈会溢出呢?

         */
    }

    // Method 'sum()' recurses infinitely, and can only end by throwing an exception
    /*
        设置递归出口后,这个方法的作用是求前num个数的和(num>0)
     */
    public static int sum(int num) {
        // 递归的出口哦
        if (num == 0) {
            return 0;
        }
        // 递归体
        return num + sum(num - 1);
    }
}
